package com.sky.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sky.annotation.AutoClean;
import com.sky.constant.MessageConstant;
import com.sky.constant.StatusConstant;
import com.sky.dto.DishDTO;
import com.sky.dto.DishPageQueryDTO;
import com.sky.entity.Dish;
import com.sky.entity.DishFlavor;
import com.sky.mapper.CategoryMapper;
import com.sky.mapper.DishFlavorMapper;
import com.sky.mapper.DishMapper;
import com.sky.mapper.SetmealDishMapper;
import com.sky.result.PageResult;
import com.sky.result.Result;
import com.sky.service.DishService;
import com.sky.vo.DishVO;
import org.springframework.beans.BeanUtils;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

@Service
public class DishServiceImpl implements DishService {
	
	private final DishMapper dishMapper;
	
	private final CategoryMapper categoryMapper;
	
	private final DishFlavorMapper dishFlavorMapper;
	
	private final SetmealDishMapper setmealDishMapper;
	
	public DishServiceImpl(DishMapper dishMapper, CategoryMapper categoryMapper
			, DishFlavorMapper dishFlavorMapper, SetmealDishMapper setmealDishMapper) {
		this.dishMapper = dishMapper;
		this.categoryMapper = categoryMapper;
		this.dishFlavorMapper = dishFlavorMapper;
		this.setmealDishMapper = setmealDishMapper;
	}
	
	@Override
	public Result dishPage(DishPageQueryDTO pageQueryDTO) {
		if (pageQueryDTO.getPage() == null) {
			pageQueryDTO.setPage(1);
		}
		if (pageQueryDTO.getPageSize() == null) {
			pageQueryDTO.setPageSize(5);
		}
		PageHelper.startPage(pageQueryDTO.getPage(), pageQueryDTO.getPageSize());
		List<Dish> dishList = dishMapper.getDishBy(pageQueryDTO.getName(), pageQueryDTO.getCategoryId(), pageQueryDTO.getStatus());
		Page<Dish> p = (Page<Dish>) dishList;
		List<DishVO> dishVOList = new ArrayList<>((int) p.getTotal());
		p.forEach(dish -> {
			DishVO dishVO = new DishVO();
			BeanUtils.copyProperties(dish, dishVO);
			dishVO.setCategoryName(categoryMapper.getCategoryBy(null, null, dish.getCategoryId()).remove(0).getName());
			dishVOList.add(dishVO);
		});
		PageResult pageResult = new PageResult();
		pageResult.setTotal(p.getTotal());
		pageResult.setRecords(dishVOList);
		return Result.success(pageResult);
	}
	
	@Transactional
	@Override
	@AutoClean
	public Result addDish(DishDTO dishDTO) {
		if (dishDTO == null || dishDTO.getCategoryId() == null || dishDTO.getName() == null
				|| dishDTO.getImage() == null || dishDTO.getPrice() == null) {
			return Result.error(MessageConstant.INCORRECT_PARAMETERS);
		}
		Dish dish = new Dish();
		BeanUtils.copyProperties(dishDTO, dish);
		dishMapper.insert(dish);
		addFlavor(dish, dishDTO);
		return Result.success();
	}
	
	
	/**
	 * 临时方案
	 * TODO 找时间优化一下
	 *
	 * @param ids
	 * @return
	 */
	@Transactional
	@Override
	@AutoClean
	public Result deleteDish(List<Long> ids) {
		for (int i = 0; i < ids.size(); i++) {
			if (Objects.equals(dishMapper.getDishBy(null, null, null, ids.get(i))
					.remove(0).getStatus(), StatusConstant.ENABLE) ||
					setmealDishMapper.getCountByDishId(ids.get(i)).size() > 0) {
				ids.remove(i--);
			}
		}
		if (ids.size() == 0) {
			return Result.error(MessageConstant.INCORRECT_PARAMETERS);
		}
		dishFlavorMapper.delete(ids);
		return Result.success(dishMapper.deleteDish(ids));
	}
	
	@Override
	@Cacheable(cacheNames = "DishCache", key = "#id")
	public Result getById(Long id) {
		if (id == null) {
			return Result.error(MessageConstant.INCORRECT_PARAMETERS);
		}
		Dish dish = dishMapper.getDishBy(null, null, null, id).remove(0);
		List<DishFlavor> flavorList = dishFlavorMapper.getBy(id);
		DishVO dishVO = new DishVO();
		BeanUtils.copyProperties(dish, dishVO);
		dishVO.setFlavors(flavorList);
		return Result.success(dishVO);
	}
	
	@Transactional
	@Override
	@AutoClean
	public Result updateDish(DishDTO dishDTO) {
		if (dishDTO == null || dishDTO.getCategoryId() == null || dishDTO.getName() == null
				|| dishDTO.getImage() == null || dishDTO.getPrice() == null) {
			return Result.error(MessageConstant.INCORRECT_PARAMETERS);
		}
		Dish dish = dishMapper.getDishBy(null, null, null, dishDTO.getId()).remove(0);
		if (dish == null) {
			return Result.error(MessageConstant.DISH_NOT_FOUND);
		}
		BeanUtils.copyProperties(dishDTO, dish);
		dishFlavorMapper.delete(Collections.singletonList(dishDTO.getId()));
		addFlavor(dish, dishDTO);
		dishMapper.updateDish(dish);
		return Result.success();
	}
	
	@Override
	@AutoClean
	public Result banDish(Integer status, Long id) {
		if (status == null || id == null) {
			return Result.error(MessageConstant.INCORRECT_PARAMETERS);
		}
		Dish dish = dishMapper.getDishBy(null, null, null, id).remove(0);
		dish.setStatus(status);
		dishMapper.updateDish(dish);
		return Result.success();
	}
	
	@Override
	@Cacheable(cacheNames = "DishCache", key = "#categoryId")
	public Result getByCategoryId(Long categoryId) {
		return Result.success(dishMapper.getByCategoryId(categoryId));
	}
	
	@Transactional//TODO 事务传播有点忘了
	public void addFlavor(Dish dish, DishDTO dishDTO) {
		List<DishFlavor> flavors = dishDTO.getFlavors();
		if (flavors.size() != 0) {
			flavors.forEach(dishFlavor -> {
				dishFlavor.setDishId(dish.getId());
				dishFlavorMapper.insert(dishFlavor);
			});
		}
	}
}
